package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcWatchSafetyRangeMapper;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.domain.DmcDevice;
import com.csun.cmny.provider.model.domain.DmcWatchSafetyRange;
import com.csun.cmny.provider.model.dto.watch.WatchSafetyRangeDto;
import com.csun.cmny.provider.model.dto.watch.WatchSafetyRangePageQuery;
import com.csun.cmny.provider.model.vo.watch.DmcWatchSafetyRangeVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.DmcDeviceService;
import com.csun.cmny.provider.service.DmcWatchSafetyRangeService;
import com.csun.cmny.util.PubUtils;
import com.csun.cmny.util.PublicUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Preconditions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-01-24 15:21
 * @Description: the class dmc watch safety range service impl
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcWatchSafetyRangeServiceImpl extends BaseService<DmcWatchSafetyRange>
        implements DmcWatchSafetyRangeService {

    @Resource
    private CmnyMessageSource cmnyMessageSource;

    @Resource
    private DmcDeviceService dmcDeviceService;

    @Resource
    private DmcWatchSafetyRangeMapper dmcWatchSafetyRangeMapper;

    /**
     * query watch safety range list with page
     *
     * @param watchSafetyRangePageQuery watch safety range query
     * @return the page info.
     */
    @Override
    public PageInfo queryWatchSafetyRangeListWithPage(WatchSafetyRangePageQuery watchSafetyRangePageQuery) {

        PageHelper.startPage(watchSafetyRangePageQuery.getPageNum(), watchSafetyRangePageQuery.getPageSize());

        List<DmcWatchSafetyRangeVo> dmcWatchSafetyRangeVoList = dmcWatchSafetyRangeMapper
                .queryWatchSafetyRangeListWithPage(watchSafetyRangePageQuery);

        return new PageInfo<>(dmcWatchSafetyRangeVoList);
    }

    /**
     * add watch safety range
     *
     * @param watchSafetyRangeDto watch safety range dto
     * @param loginAuthDto        login auth dto
     * @return the int.
     */
    @Override
    public Integer addWatchSafetyRange(WatchSafetyRangeDto watchSafetyRangeDto, LoginAuthDto loginAuthDto) {

        // 1.校验设备Id
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsWatchByDeviceId(watchSafetyRangeDto.getDeviceId());
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610014, watchSafetyRangeDto.getDeviceId());
        }

        // 2.校验名称
        Preconditions.checkArgument(!PubUtils.isNull(watchSafetyRangeDto.getName()),
                cmnyMessageSource.getMessage("watch.safety.range.name.null", null));

        // 3.校验开关
        Preconditions.checkArgument(watchSafetyRangeDto.getIsOpen() != null,
                cmnyMessageSource.getMessage("watch.safety.range.is.open.null", null));

        Preconditions.checkArgument(watchSafetyRangeDto.getIsOpen() >= 0
                        && watchSafetyRangeDto.getIsOpen() <= 1,
                cmnyMessageSource.getMessage("watch.safety.range.is.open.range", null));

        // 4.校验报警方式
        Preconditions.checkArgument(watchSafetyRangeDto.getAlertWay() != null,
                cmnyMessageSource.getMessage("watch.safety.range.alert.way.null", null));

        Preconditions.checkArgument(watchSafetyRangeDto.getAlertWay() >= 0
                        && watchSafetyRangeDto.getAlertWay() <= 2,
                cmnyMessageSource.getMessage("watch.safety.range.alert.way.range", null));

        // 5.校验gps
        Preconditions.checkArgument(!PubUtils.isNull(watchSafetyRangeDto.getGpsString()),
                cmnyMessageSource.getMessage("watch.safety.range.gps.null", null));

        // 6.校验位置
        Preconditions.checkArgument(!PubUtils.isNull(watchSafetyRangeDto.getLocation()),
                cmnyMessageSource.getMessage("watch.safety.range.location.null", null));

        // 7.校验安全距离
        Preconditions.checkArgument(watchSafetyRangeDto.getSafetyRange() != null,
                cmnyMessageSource.getMessage("watch.safety.range.null", null));

        Preconditions.checkArgument(watchSafetyRangeDto.getSafetyRange() >= 100,
                cmnyMessageSource.getMessage("watch.safety.range.error", null));

        // 8.校验是否有重复名称的安全区域(同一手环)
        DmcWatchSafetyRange dmcWatchSafetyRangeQuery = new DmcWatchSafetyRange();
        dmcWatchSafetyRangeQuery.setDeviceId(watchSafetyRangeDto.getDeviceId());
        dmcWatchSafetyRangeQuery.setName(watchSafetyRangeDto.getName());
        dmcWatchSafetyRangeQuery = dmcWatchSafetyRangeMapper.selectOne(dmcWatchSafetyRangeQuery);
        if (PublicUtil.isNotEmpty(dmcWatchSafetyRangeQuery)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610047);
        }

        // 8.添加安全范围
        DmcWatchSafetyRange dmcWatchSafetyRange = new DmcWatchSafetyRange();
        BeanUtils.copyProperties(watchSafetyRangeDto, dmcWatchSafetyRange);
        dmcWatchSafetyRange.setUpdateInfo(loginAuthDto);
        Integer result = dmcWatchSafetyRangeMapper.insertSelective(dmcWatchSafetyRange);

        return result;
    }

    /**
     * edit watch safety range
     *
     * @param watchSafetyRangeDto watch safety range dto
     * @param loginAuthDto        login auth dto
     * @return the int.
     */
    @Override
    public Integer editWatchSafetyRange(WatchSafetyRangeDto watchSafetyRangeDto, LoginAuthDto loginAuthDto) {

        // 1.校验id
        Preconditions.checkArgument(watchSafetyRangeDto.getId() != null,
                cmnyMessageSource.getMessage("watch.safety.range.id.null", null));

        // 2.校验安全区域是否存在
        DmcWatchSafetyRange dmcWatchSafetyRangeQuery = dmcWatchSafetyRangeMapper
                .selectByPrimaryKey(watchSafetyRangeDto.getId());
        if (PublicUtil.isEmpty(dmcWatchSafetyRangeQuery)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610048);
        }

        // 3.校验开关
        if (PublicUtil.isNotEmpty(watchSafetyRangeDto.getIsOpen())) {
            Preconditions.checkArgument(watchSafetyRangeDto.getIsOpen() != null,
                    cmnyMessageSource.getMessage("watch.safety.range.is.open.null", null));

            Preconditions.checkArgument(watchSafetyRangeDto.getIsOpen() >= 0
                            && watchSafetyRangeDto.getIsOpen() <= 1,
                    cmnyMessageSource.getMessage("watch.safety.range.is.open.range", null));
        }

        // 4.校验报警方式
        if (PublicUtil.isNotEmpty(watchSafetyRangeDto.getAlertWay())) {
            Preconditions.checkArgument(watchSafetyRangeDto.getAlertWay() != null,
                    cmnyMessageSource.getMessage("watch.safety.range.alert.way.null", null));

            Preconditions.checkArgument(watchSafetyRangeDto.getAlertWay() >= 0
                            && watchSafetyRangeDto.getAlertWay() <= 2,
                    cmnyMessageSource.getMessage("watch.safety.range.alert.way.range", null));
        }

        // 6.校验安全距离
        if (PublicUtil.isNotEmpty(watchSafetyRangeDto.getSafetyRange())) {
            Preconditions.checkArgument(watchSafetyRangeDto.getSafetyRange() != null,
                    cmnyMessageSource.getMessage("watch.safety.range.null", null));

            Preconditions.checkArgument(watchSafetyRangeDto.getSafetyRange() >= 100,
                    cmnyMessageSource.getMessage("watch.safety.range.error", null));
        }

        // 8.校验是否有重复名称的安全区域(同一手环)
        Long deviceId = dmcWatchSafetyRangeQuery.getDeviceId();
        dmcWatchSafetyRangeQuery = new DmcWatchSafetyRange();
        dmcWatchSafetyRangeQuery.setDeviceId(deviceId);
        dmcWatchSafetyRangeQuery.setName(watchSafetyRangeDto.getName());
        dmcWatchSafetyRangeQuery = dmcWatchSafetyRangeMapper.selectOne(dmcWatchSafetyRangeQuery);
        if (PublicUtil.isNotEmpty(dmcWatchSafetyRangeQuery)
                && !dmcWatchSafetyRangeQuery.getId().equals(watchSafetyRangeDto.getId())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610047);
        }

        // 7.更新安全范围
        DmcWatchSafetyRange dmcWatchSafetyRange = new DmcWatchSafetyRange();
        BeanUtils.copyProperties(watchSafetyRangeDto, dmcWatchSafetyRange);
        dmcWatchSafetyRange.setDeviceId(null);
        dmcWatchSafetyRange.setUpdateInfo(loginAuthDto);

        Integer result = dmcWatchSafetyRangeMapper.updateByPrimaryKeySelective(dmcWatchSafetyRange);

        return result;
    }

    /**
     * delete watch safety range by id
     *
     * @param id id
     * @return the int.
     */
    @Override
    public Integer deleteWatchSafetyRangeById(Long id) {

        // 1.校验id
        Preconditions.checkArgument(id != null,
                cmnyMessageSource.getMessage("watch.safety.range.id.null", null));

        Integer result = dmcWatchSafetyRangeMapper.deleteByPrimaryKey(id);

        return result;
    }

    /**
     * get watch safety range by id
     *
     * @param id id
     * @return the int.
     */
    @Override
    public DmcWatchSafetyRangeVo getWatchSafetyRangeById(Long id) {

        // 1.校验id
        Preconditions.checkArgument(id != null,
                cmnyMessageSource.getMessage("watch.safety.range.id.null", null));

        DmcWatchSafetyRangeVo dmcWatchSafetyRangeVo = dmcWatchSafetyRangeMapper.getWatchSafetyRangeById(id);

        return dmcWatchSafetyRangeVo;
    }

    /**
     * delete watch safety range by device id
     *
     * @param deviceId device id
     * @return the int.
     */
    @Override
    public Integer deleteWatchSafetyRangeByDeviceId(Long deviceId) {
        return null;
    }

    /**
     * romve dmc safete range
     *
     * @param deviceId device id
     * @return the int.
     */
    @Override
    public Integer removeDmcSafetyRange(Long deviceId) {

        DmcWatchSafetyRange dmcWatchSafetyRange = new DmcWatchSafetyRange();
        dmcWatchSafetyRange.setDeviceId(deviceId);

        return dmcWatchSafetyRangeMapper.delete(dmcWatchSafetyRange);
    }
}
